package daos

import (
	"Bok/models"

	"gorm.io/gorm"
)

// 定义接口，限定数据访问方法
// 接口首字母大写
// 接口的方法无非：“增删改查” CRUD
// XXXDao 表表示是数据访问的 数据结构，用于直接和 数据库打交道
// 接口写声明就行了，不用写实现，即：函数三要素
type ArticalDao interface {
	// 注意参数都传入 指针的形式，节省内存空间
	Create(v *models.Article) (err error)
	GetById(id uint) (v *models.Article, err error)
	List(page, pageSize int, state string) ([]models.Article, int64, error)
	Update(v *models.Article) (err error)
	Delete(id uint) (err error)
}

// 实际操作数据库的数据类型
type articleDao struct {
	db *gorm.DB
}

// go 的实现接口 是鸭子类型，只要走路 和 叫声像鸭子就行了

// 初始化 书记库操作对象实例
func NewArticleDao(db *gorm.DB) ArticalDao {
	return &articleDao{db: db}
}

// 让这个数据结构实现 接口的方法
func (d *articleDao) Create(v *models.Article) (err error) {
	return d.db.Create(v).Error
}

func (d *articleDao) GetById(id uint) (v *models.Article, err error) {
	var ret models.Article
	err = d.db.First(&ret, "id=?", id).Error
	return &ret, err
}
func (d *articleDao) List(page, pageSize int, state string) ([]models.Article, int64, error) {
	var articles []models.Article
	var total int64
	query := d.db.Model(&models.Article{})
	if state != "" {
		query = query.Where("state = ?", state)
	}

	// 计算总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}
	// 分页查询
	offset := (page - 1) * pageSize
	err := query.
		Order("created_at DESC").
		Offset(offset).
		Limit(pageSize).
		Find(&articles).Error

	return articles, total, err
}
func (d *articleDao) Update(v *models.Article) (err error) {
	return d.db.Save(v).Error
}

// &models.Article{} 创建了一个models.Article结构体的空实例，并获取其指针。
// 这个空实例用于告诉GORM要操作的是哪个模型（即数据库中的哪张表）
func (d *articleDao) Delete(id uint) (err error) {
	return d.db.Delete(&models.Article{}, id).Error
}
